package com.qyl.framework.server.encoder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.qyl.framework.base.Message;
import com.qyl.framework.base.protocol.ResponseProto;
import com.qyl.framework.base.response.RpcReponse;
import com.qyl.framework.utils.ParamsUtils;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

public class ResponseProtoEncoder extends MessageToByteEncoder<ResponseProto>{

	private Logger logger= LoggerFactory.getLogger(ResponseProtoEncoder.class);
	
	@Override
	protected void encode(ChannelHandlerContext ctx, ResponseProto msg, ByteBuf out) throws Exception {
		long responseId = msg.getReponseId();
		out.writeLong(responseId);
		logger.info("ResponseProtoEncoder respose for reposneId={}", responseId);
		
		String responseClassName = msg.getResponse().getClass().getName();
		byte[] responseClassNameBytes = responseClassName.getBytes();
		out.writeByte(responseClassNameBytes.length);
		out.writeBytes(responseClassNameBytes);
		
		if (RpcReponse.class.isAssignableFrom(msg.getResponse().getClass())) {
			ByteBuf buffer = ParamsUtils.toBuffer((Message)msg.getResponse());
			out.writeBytes(buffer);
		} else if (isPrimitiveOrString(msg.getResponse().getClass())) {
			ByteBuf buffer = ParamsUtils.toBufferForSimpleType(msg.getResponse());
			out.writeBytes(buffer);
		} else {
			//非基本类 [byte, int, short, long, boolean, float, double], String , Message实现类，协议数据直接discard
			return;
		}
	}

	private boolean isPrimitiveOrString(Class<?> classz) {
		if (classz == Byte.class || classz == byte.class){
			return true;
		} else if (classz == Short.class || classz == short.class){
			return true;
		} else if (classz == Long.class || classz == Long.class){
			return true;
		} else if (classz == Boolean.class || classz == boolean.class){
			return true;
		} else if (classz == Float.class || classz == float.class){
			return true;
		} else if (classz == Double.class || classz == double.class){
			return true;
		} else if (classz == Character.class || classz == char.class){
			return true;
		} else if (classz == String.class){
			return true;
		}
		return false;
	}
}
